/*
 * power.h
 *
 * The power driver for SinhMicro's SINH51 platform.
 *
 * Copyright (C) 2024 Sinh Micro, Inc.
 * Subject to the GNU Public License, version 2.
 *
 * Author: lixiang<lixiang@sinhmicro.com>
 * 
 * Encoding format: GB2312
 * Version: v1.2.2
 * Date: 2024-11-05
 */

#ifndef __HAL_POWER_H__
#define __HAL_POWER_H__

#include "hal-config.h"

#include "types.h"

/*
 * In order to optimize the code size, we MUST realize
 * the most of POWER's API using Macro, please realize these APIs as below:
 * 1. Get the DCIN's, VIN's or VKEY's OK STATUS(1, OK; 0, non-OK)
 *    POWER_IS_DCIN_OK()
 *    POWER_IS_VIN_OK()
 *    POWER_IS_VKEY_OK()
 *
 * 2. enable or disable LVR(Low VDD Reset) function
 *    POWER_LVR_ENABLE()
 *    POWER_LVR_DISABLE()
 *
 * 3. make CPU into IDLE mode
 *    POWER_CPU_IDLE()
 * 
 * 4. enable/disable AlwaysTimer wakeup
 *    POWER_ATIMER_WAKEUP_ENABLE()
 *    POWER_ATIMER_WAKEUP_DISABLE()
 * 
 * 5. get AlwaysTimer's wakeup flag (1, true; 0, false)
 *    POWER_IS_ATIMER_WAKEUP()
 * 
 * 6. clear AlwaysTimer's wakeup flag
 *    POWER_CLR_ATIMER_WAKEUP()  
 */ 

#include "power/power-ss805x.h"      

#define POWER_WAKEUP_MODE_DISABLE       (0)     // disable
#define POWER_WAKEUP_MODE_LOW           (1)     // low(de-active)
#define POWER_WAKEUP_MODE_HIGH          (2)     // high(active)
#define POWER_WAKEUP_MODE_H2L           (3)     // high to low(fall edge)
#define POWER_WAKEUP_MODE_L2H           (4)     // low to high(rise edge)
#define POWER_WAKEUP_MODE_CHANGE        (5)     // low to high or high to low(dual edge)

#define POWER_WAKEUP_SOURCE_INVALID     (0)
#define POWER_WAKEUP_SOURCE_DCIN        (1)
#define POWER_WAKEUP_SOURCE_ATIMER      (2)     //always timer      

typedef uint16_t power_wakeup_source_t;

#define POWER_WAKEUP_GET_MODE(src)      (((src) >> 12) & 0x0F)
#define POWER_WAKEUP_GET_OTHER_SRC(src) (((src) >> 8) & 0x0F)
#define POWER_WAKEUP_GET_IO_SRC(src)    ((src) & 0xFF)

/*
 * this function is used to initialize the POWER driver.
 *
 * @param[in]  None
 */
void power_init(void);

/*
 * this function is used to de-initialize the POWER driver.
 *
 * @param[in]  None
 */
void power_exit(void);

/*
 * this function should be called before ENTERING SLEEP MODE.
 *
 * @param[in]  None
 */
void power_pre_sleep(void);

/*
 * this function will make system into SLEEP MODE,
 * after wakeup, system will reset and re-run.
 *
 * @param[in]  None
 */
void power_enter_sleep(void);

/*
 * this function will check the wakeup reasons,
 * if system is waked up by the specail wakeup source,
 * the checking will be TRUE, and then,
 * this wakeup source wakeup flags will be cleared.
 *
 * @param[in] is_io_src the wakeup source's type
 *                      true:  I/O source
 *                      false: other source
 * @param[in] source the wakeup source
 *                   0x11, 0x22, etc. for i/o source
 *                   POWER_WAKEUP_SOURCE_*  for other source
 * @return if this source waked up the system, YES for true, NO for false
 */
bool power_check_and_clear_sleep_reason(bool is_io_src, uint8_t source);

#endif
